//
// Created by guoshunw on 24-3-29.
//

#ifndef CMAKE_HELLO_APP_CONTEXT_H
#define CMAKE_HELLO_APP_CONTEXT_H


#include "log.h"
#include "omx_callback_base.h"

#include "memory"
#include <pthread.h>


#include <OMX_Audio.h>
#include <OMX_Core.h>
extern "C" {
#include <tsemaphore.h>
}


#define AUDIO_SINK "OMX.st.alsa.alsasink"
#define SINK_ROLE "alsa.alsasink"
#define AUDIO_EFFECT "OMX.st.volume.component"
#define AUDIO_SRC "OMX.st.alsa.alsasrc"

#define COMPONENT_NAME_BASE_LEN 20
#define MPEG4_TYPE_SEL 1

namespace openmax::callback{
    class OMXCallbackBase;
}

namespace openmax::test {

    class AppContext {
    public:
        explicit AppContext();
        virtual ~AppContext();

        OMX_ERRORTYPE Start();
        OMX_ERRORTYPE Stop();

        [[nodiscard]] OMX_BOOL IsEos() const { return is_eos_; }
        void SetEos(OMX_BOOL isEos) { is_eos_ = isEos; }

        long FillBuffer(OMX_U8* buf, size_t size);
        long FillBuffer(OMX_BUFFERHEADERTYPE* buf);

        long SyncFillBuffer();
    private:
        std::shared_ptr<tsem_t> src_event_sem_{};
        std::shared_ptr<tsem_t> sink_event_sem_{};
        std::shared_ptr<tsem_t> volume_event_sem_{};

        std::mutex buffer_mutex_;
        std::shared_ptr<tsem_t> eof_sem_{};

        OMX_HANDLETYPE audio_sink_handle_{};

        std::shared_ptr<openmax::callback::OMXCallbackBase> audio_sink_callbacks_{};

        OMX_HANDLETYPE audio_src_handle_{};
        std::string input_pcm_file_ = "../resources/outfile_s16le_48k_stereo.pcm";
        std::shared_ptr<std::ifstream> input_pcm_file_stream_{};

        OMX_HANDLETYPE volume_handle_{};

        OMX_ERRORTYPE Init();
        OMX_ERRORTYPE DeInit();
        OMX_ERRORTYPE InitGain();

        OMX_BUFFERHEADERTYPE *in_buffer_volume_[2]{}, *out_buffer_volume_[2]{};
        OMX_BUFFERHEADERTYPE *in_buffer_sink_[2]{};

        OMX_BUFFERHEADERTYPE *out_buffer_src_[2]{};
        OMX_AUDIO_PARAM_PCMMODETYPE s_pcm_mode_param_{};

        int buffer_in_size = 10 * 8192;
        int buffer_out_size = 10 * 8192;

        OMX_BOOL is_eos_ = OMX_FALSE;
        int gain = 1;
    };

}// namespace openmax::test


#endif//CMAKE_HELLO_APP_CONTEXT_H
